home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 2
/
The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO
/
clang
/
nn.zip
/
GLOBAL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-31
|
10KB
|
549 lines
#include <signal.h>
#include <errno.h>
#include <pwd.h>
#include "config.h"
export char *home_directory;
export char *nn_directory;
export char news_directory[] = NEWS_DIRECTORY; /* /usr/spool/news */
export char lib_directory[] = LIB_DIRECTORY; /* /usr/local/lib/nn */
export char db_directory[] = DB_DIRECTORY; /* /usr/spool/nn */
export char *log_entry_filter = NULL;
export char *temp_file;
export char *pager = PAGER; /* pg or more */
export int is_master;
#ifdef HAVE_MULTIGROUP
#ifndef NGROUPS
#include <sys/param.h>
#endif
#ifndef GIDSET_TYPE
#define GIDSET_TYPE int
#endif
static int ngroups;
static GIDSET_TYPE gidset[NGROUPS];
static in_grplist(gid)
GIDSET_TYPE gid;
{
int n;
for (n = 0; n < ngroups; ++n)
if (gidset[n] == gid) return 1;
return 0;
}
#define group_access(gpid) in_grplist((GIDSET_TYPE)(gpid))
#else
#define group_access(gid) ((gid) == group_id)
#endif
/* signal handler interface */
export int s_hangup = 0; /* hangup signal */
export int s_keyboard = 0; /* keyboard interrupt */
export int s_pipe = 0; /* broken pipe */
export int s_redraw = 0; /* redraw signal (if job control) */
static sig_type catch_hangup(n)
{
signal(n, SIG_IGN);
s_hangup++;
}
static sig_type catch_keyboard(n)
{
s_keyboard++;
#ifdef RESET_SIGNAL_WHEN_CAUGHT
signal(n, catch_keyboard);
#endif
}
static sig_type catch_pipe(n)
{
s_pipe++;
#ifdef RESET_SIGNAL_WHEN_CAUGHT
signal(n, catch_pipe);
#endif
}
#ifdef HAVE_JOBCONTROL
static sig_type catch_suspend(n)
{
s_redraw++;
#ifdef RESET_SIGNAL_WHEN_CAUGHT
signal(n, catch_redraw);
#endif
suspend_nn();
}
#endif
/*
* who:
* 0 nn
* 1 nnmaster
* 2 nnadmin
* 3 nncheck
*/
init_global(who)
int who;
{
char *env;
unsigned short getuid(), getgid();
int getpid();
int suspend_nn();
is_master = (who == 1);
signal(SIGTERM, catch_hangup);
signal(SIGHUP, catch_hangup);
signal(SIGPIPE, catch_pipe);
signal(SIGALRM, SIG_IGN);
#ifdef SIGPWR
signal(SIGPWR, catch_hangup);
#endif
user_id = getuid();
#ifdef HAVE_MULTIGROUP
ngroups = getgroups(NGROUPS, gidset); /* Get users's group set */
group_id = gidset[0]; /* not used, but just in case... */
#else
group_id = getgid();
#endif
process_id = getpid();
if (is_master) {
signal(SIGINT, catch_hangup);
signal(SIGQUIT, catch_hangup);
return 0;
}
signal(SIGINT, catch_keyboard);
signal(SIGQUIT, catch_keyboard);
#ifdef HAVE_JOBCONTROL
signal(SIGTSTP, catch_suspend);
#endif
if ((home_directory = getenv("HOME")) == NULL)
user_error("No HOME environment variable");
nn_directory = mk_file_name(home_directory, ".nn");
if (who != 2 && !file_exist(nn_directory, "drwx")) {
if (who == 3) return -1;
mkdir(nn_directory, 0755); /* should check here */
}
return 0;
}
new_temp_file()
{
static char buf[FILENAME];
static char *temp_dir = NULL;
if (temp_dir == NULL && (temp_dir = getenv("TMPDIR")) == NULL)
temp_dir = TMP_DIRECTORY;
sprintf(buf, "%s/nn.XXXXXX", temp_dir);
mktemp(buf);
temp_file = buf;
}
/*
* this is for admin K & W commands and for master -w
*/
kill_master(sig)
int sig;
{
FILE *m_pid;
int pid, ok;
char buf[10];
m_pid = open_file(relative(lib_directory, "MPID"), OPEN_READ);
if (m_pid == NULL) {
errno = ESRCH;
return 0;
}
ok = 0; /* not yet */
if (fgets(buf, 10, m_pid) == NULL)
printf("MPID file is empty\n");
else {
pid = atoi(buf);
if (pid <= 2)
printf("MPID file contains illegal process id: %d\n", pid);
else
if (kill(pid, sig) != -1) ok++;
}
fclose(m_pid);
return ok;
}
mem_check(addr, size, msg)
char *addr, *msg;
int size;
{
if (addr == NULL) {
if (is_master)
sys_error("Cannot allocate %d %s", size, msg);
else
user_error("Cannot allocate %d %s", size, msg);
}
}
FILE *open_file(name, mode)
char *name;
int mode;
{
FILE *f;
int fd;
if ((mode & DONT_CREATE) && !file_exist(name, (char *)NULL))
return NULL;
switch (mode & 0x0f) {
case OPEN_READ:
f = fopen(name, "r");
break;
case OPEN_UPDATE:
/* f = fopen(name, "r+"); -- not reliable on many systems (sigh) */
if ((fd = open(name, O_WRONLY)) >= 0) {
if ((f = fdopen(fd, "w")) != NULL) return f;
close(fd);
}
/* fall thru */
case OPEN_CREATE:
f = fopen(name, "w");
break;
case OPEN_APPEND:
f = fopen(name, "a");
break;
default:
sys_error("Illegal mode: open_file(%s, %d)", name, mode);
}
if (f) {
if (mode & OPEN_UNLINK) unlink(name);
return f;
}
if ((mode & MUST_EXIST) == 0) return NULL;
if (is_master)
sys_error("Cannot open file %s, mode: %d", name, mode);
else {
log_entry('R', "Client cannot open file %s, mode: %d", name, mode);
user_error("Cannot open file %s", name);
}
return NULL;
}
/*
* relative -- concat directory name and file name
*/
char *relative(dir, name)
char *dir, *name;
{
static char concat_path[FILENAME];
sprintf(concat_path, "%s/%s", dir, name);
return concat_path;
}
char *mk_file_name(dir, name)
char *dir, *name;
{
char *buf;
buf = malloc((unsigned)(strlen(dir) + strlen(name) + 2));
mem_check(buf, 1, "file name");
sprintf(buf, "%s/%s", dir, name);
return buf;
}
char *home_relative(dir)
char *dir;
{
if (dir) {
if (*dir == '/')
return copy_str(dir);
else {
if (*dir == '~' && *++dir == '/') dir++;
return mk_file_name(home_directory, dir);
}
}
return NULL;
}
char *copy_str(str)
char *str;
{
char *new;
new = malloc((unsigned)(strlen(str) + 1));
mem_check(new, 1, "string");
if (new) strcpy(new, str);
return new;
}
time_t m_time(f)
FILE *f;
{
struct stat st;
if (fstat(fileno(f), &st) < 0) return 0;
return st.st_mtime;
}
time_t file_exist(name, mode)
char *name;
char *mode;
{
struct stat statb;
extern int errno;
if (stat(name, &statb)) return 0;
if (mode == NULL) return statb.st_mtime;
while (*mode) {
switch (*mode++) {
case 'd':
if ((statb.st_mode & S_IFMT) == S_IFDIR) continue;
errno = ENOTDIR;
return 0;
case 'f':
if ((statb.st_mode & S_IFMT) == S_IFREG) continue;
if ((statb.st_mode & S_IFMT) == 0000000) continue;
if ((statb.st_mode & S_IFMT) == S_IFDIR) {
errno = EISDIR;
return 0;
}
break;
case 'r':
if ((statb.st_mode & 0400) && statb.st_uid == user_id) continue;
if ((statb.st_mode & 0040) && group_access(statb.st_gid)) continue;
if ((statb.st_mode & 0004)) continue;
break;
case 'w':
if ((statb.st_mode & 0200) && statb.st_uid == user_id) continue;
if ((statb.st_mode & 0020) && group_access(statb.st_gid)) continue;
if ((statb.st_mode & 0002)) continue;
break;
case 'x':
if ((statb.st_mode & 0100) && statb.st_uid == user_id) continue;
if ((statb.st_mode & 0010) && group_access(statb.st_gid)) continue;
if ((statb.st_mode & 0001)) continue;
break;
}
errno = EACCES;
return 0;
}
/* all modes are ok */
return statb.st_mtime;
}
print_version(fmt)
char *fmt;
{
extern int Update_Level, Patch_Level;
int param;
for (; *fmt; fmt++) {
if (*fmt == '%') {
switch (*++fmt) {
case 'R':
param = RELEASE;
break;
case 'V':
param = VERSION;
break;
case 'P':
param = Patch_Level;
break;
case 'U':
param = Update_Level;
break;
default:
continue;
}
printf("%d", param);
continue;
}
putchar(*fmt);
}
fl;
}
/*VARARGS*/
log_entry(va_alist)
va_dcl
{
int type, rval;
va_list ap;
va_start(ap);
type = va_arg1(int);
rval = enter_log(type, va_args2toN);
va_end(ap);
return rval;
}
#ifdef HAVE_SYSLOG
#include <syslog.h>
#endif /* HAVE_SYSLOG */
/*VARARGS*/
sys_error(va_alist)
va_dcl
{
char buf[512];
char *fmt;
FILE *f;
va_list ap;
va_start(ap);
enter_log('E', va_args1toN);
va_end(ap);
if (is_master) {
va_start(ap);
fmt = va_arg1(char *);
vsprintf(buf, fmt, va_args2toN);
va_end(ap);
#ifndef HAVE_SYSLOG
f = open_file("/dev/console", OPEN_CREATE);
if (f == NULL) nn_exit(8);
fprintf(f, "\n\rNNMASTER FATAL ERROR\n\r%s\n\n\r", buf);
fclose(f);
#else /* HAVE_SYSLOG */
openlog("nnmaster", LOG_CONS, LOG_DAEMON);
syslog(LOG_ALERT, "%s", buf);
closelog();
#endif /* HAVE_SYSLOG */
}
nn_exit(7);
}
static enter_log(type, va_tail)
char type;
va_tdcl
{
FILE *log;
char *msg, buf[512], logname[512];
if (log_entry_filter != NULL)
for (msg = log_entry_filter; *msg; msg++)
if (*msg == type) return 1;
msg = va_arg1(char *);
vsprintf(buf, msg, va_args2toN);
/* cannot use relative: one of the args may be generated by it */
sprintf(logname, "%s/Log", lib_directory);
log = open_file(logname, OPEN_APPEND);
if (log == NULL) return 0;
fprintf(log, "%c: %s (%s): %s\n", type,
date_time((time_t)0), user_name(), buf);
fclose(log);
return 1;
}
char *user_name()
{
static char *user = NULL;
struct passwd *pw, *getpwuid();
if (is_master) return "M";
if (user == NULL) {
pw = getpwuid((int)user_id);
if (pw == NULL) user = "?";
user = copy_str(pw->pw_name);
}
return user;
}
char *date_time(t)
time_t t;
{
char *str;
if (t == (time_t)0) time(&t);
str = ctime(&t);
str[16] = 0;
return str+4;
}
#ifndef HAVE_MKDIR
mkdir(path, mode)
char *path;
int mode;
{
char command[FILENAME*2 + 20];
sprintf(command, "{ mkdir %s && chmod %o %s ; } > /dev/null 2>&1",
path, mode, path);
return system(command);
}
#endif